<?php

namespace App\Modules\Order\Repositories;

use App\Exceptions\AllValidatorException;
use App\Exceptions\ExistedException;
use App\Exceptions\NotFoundException;
use App\Lib\Utilities;
use App\Models\Order;
use App\Modules\DataCenter\Repositories\VisitHistoryRepository;
use App\Modules\Employee\Repositories\DynamicRepository;
use App\Modules\Employee\Repositories\EmployeeRepository;
use App\Modules\Employee\Repositories\UserCoinRepository;
use App\Modules\Member\Repositoryies\MemberRepository;
use App\Modules\Order\Criterias\findOrderAppBarberCriteria;
use App\Modules\Order\Criterias\findOrderAppStoreCriteria;
use App\Modules\Order\Criterias\findOrderStatisticsCriteria;
use App\Modules\Order\Criterias\GetAppointmentAppCriteria;
use App\Modules\Order\Criterias\getAppointmentListCriteria;
use App\Modules\Order\Criterias\getCenterOrderListCriteria;
use App\Modules\Order\Criterias\getContributionOrderServiceListCriteria;
use App\Modules\Order\Criterias\GetOrderDetailInfoIncludeItemsByOrderIdCriteria;
use App\Modules\Order\Criterias\getOrderPointListCriteria;
use App\Modules\Order\Criterias\orderTodayCriteria;
use App\Modules\Order\Criterias\searchOrderWxCriteria;
use App\Modules\Order\Validators\OrderValidator;

use App\Modules\Service\Repositories\ServiceRepository;
use App\Modules\Store\Repositories\StoreRepository;
use App\Modules\System\Repositories\UserStoreRepository;
use Flower\Core\Repository\Eloquent\BaseRepository;
use Flower\Core\Repository\Exceptions\ValidatorException;
use function foo\func;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\MessageBag;

class OrderRepository extends BaseRepository
{
	/**
	 * Specify Model class name
	 * @return string
	 */
	public function model()
	{
		return Order::class;
	}

	/**
	 * Specify Validator class name
	 * @return mixed
	 */
	public function validator()
	{
		return OrderValidator::class;
	}

	/**
	 * Specify Presenter class name
	 * @return mixed
	 */
	public function presenter()
	{
		// return OrderPresenter::class;
		//return ModelFractalPresenter::class;
	}

	/**
	 * 预约列表
	 * @param $requestData
	 * @return array
	 */
	public function appointmentSchedule($requestData)
	{
		//已经预约的列表
		$list = (new AppointmentRepository())->getAppointmentList($requestData)->pluck(['appointment_time'])->toArray();
		// 查询店铺的营业时间

		$openCloseTime = (new StoreRepository())->getOpenTimes($requestData);
		$newList = [
			'barber_id' => $requestData['barber_id'],
			'store_id'  => $requestData['store_id']
		];

		if (empty($list)) {
			foreach ($openCloseTime as $v) {
				$newList['appointmentList'][] = [
					'time'   => date('H:i', $v),
					'status' => 0,
				];
			}
		} else {
			foreach ($openCloseTime as $v) {
				$newList['appointmentList'][] = in_array($v, $list) ? [
					'time'   => date('H:i', $v),
					'status' => 1
				] : [
					'time'   => date('H:i', $v),
					'status' => 0,
				];
			}
		}
		return $newList;
	}

	/**
	 * 订单表 新增订单
	 * @param $orderNo
	 * @param $storeId
	 * @param $barberId
	 * @param int $appointmentId
	 * @param int $price
	 * @param int $realPrice
	 * @param int $appointmentTime
	 * @param int $isAppoint
	 * @param int $source
	 * @param int $payment
	 * @param int $memberId
	 * @param int $memberCard
	 * @param int $status
	 * @param int $isPay
	 * @param int $canceler
	 * @param string $remark
	 * @return mixed
	 */
	public function addNewOrderInfo($orderNo, $storeId, $barberId, $appointmentId = 0, $price = 0, $realPrice = 0, $appointmentTime = 0, $isAppoint = 0, $source = 1, $payment = 0, $memberId = 0, $memberCardId = 0, $status = 1, $isPay = 0, $canceler = 0, $remark = '', $assistantId = 0, $changeReason = null, $finishRemark = null)
	{
		$isAppoint = isset($isAppoint) ? $isAppoint : 0;
		$params = [
			'order_no'         => $orderNo,
			'appointment_id'   => $appointmentId,
			'store_id'         => $storeId,
			'barber_id'        => $barberId,
			'price'            => $price,
			'real_price'       => $realPrice,
			'source'           => $source,
			'payment'          => $payment,
			'member_id'        => $memberId,
			'member_card_id'   => empty($memberCardId) ? 0 : $memberCardId,
			'status'           => empty($status) ? 1 : $status,
			'is_pay'           => empty($isPay) ? 0 : $isPay,
			'appointment_time' => $appointmentTime,
			'is_appoint'       => $source == config('constant.appointment.online') ? 1 : $isAppoint,
			'canceler'         => empty($canceler) ? 0 : $canceler,
			'remark'           => $remark,
			'assistant_id'     => empty($assistantId) ? 0 : $assistantId,
			'accept_time'      => time(),
			'change_reason'    => empty($changeReason) ? "" : $changeReason,
			'finish_remark'    => empty($finishRemark) ? "" : $finishRemark,
			'finish_time'      => ($source == config('constant.appointment.store') || $source == config('constant.appointment.member_card_offline')) ? time() : null
		];
		return $this->create($params);
	}

	/**
	 * 订单完成 内容修改
	 * @param $orderId
	 * @param $realPrice
	 * @param $price
	 * @param $assistantId
	 * @param $payment
	 * @param $memberCardId
	 * @param $finishedRemark
	 * @param $changeReason
	 * @return mixed
	 * @author Happy dong
	 * @modifiedTime 2019-08-11 23:19
	 */
	public function finishedById($orderId, $realPrice, $price, $payment, $memberCardId, $finishedRemark, $changeReason)
	{
		$params = [
			'price'          => $price,
			'real_price'     => $realPrice,
			'payment'        => $payment,
			'member_card_id' => $memberCardId,
			'is_pay'         => 1,
			'finish_remark'  => empty($finishedRemark) ? '' : $finishedRemark,
			'change_reason'  => empty($changeReason) ? '' : $changeReason,
			'status'         => config('constant.orderStatus.done'),
			'finish_time'    => time()
		];

		return $this->update($params, $orderId);
	}


	/**
	 * 订单完成
	 * @param $requestData
	 * @return bool
	 * @throws NotFoundException
	 */
	public function finished($requestData)
	{
		$order = $this->isExisted($requestData['order_id']);
		$service = (new ServiceRepository())->isExisted($requestData['service_id']);
		DB::beginTransaction();
		// 写入订单表
		$this->done($order, $service, $requestData);
		// 写入订单服务表
		$res = (new OrderItemRepository())->add($order->id, $service->toArray(), $requestData);
		// 写积分
		(new UserCoinRepository())->add($order->barber_id, $order->store_id, 0.1, 1, $order->id);
		// 写入提成表
		(new RoyaltyRepository())->add($order, $service, 1);
		(is_object($res) && $order) ? DB::commit() : DB::rollBack();
		return is_object($res);
	}

	/**
	 * 订单是否被处理
	 * @param $ids
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function isHandel($ids)
	{
		$orderInfo = $this->find($ids);
		if (empty($orderInfo)) {
			throw new NotFoundException(['msg' => '该订单不存在，请您重新核对订单号']);
		}
		if ($orderInfo->status > 1) {
			throw new AllValidatorException(['msg' => '该订单已经被处理过，您不能再次处理']);
		}
		return $orderInfo;
	}
//	/**
//	 * 订单完成的具体操作
//	 * @param $order Object
//	 * @param $service Object
//	 * @param $requestData Array
//	 * @return mixed
//	 */
//	private function done($order, $service, $requestData)
//	{
//		//服务次数
//		$count = isset($requestData['count']) ? $requestData['count'] : 1;
//		$order->price = round(($service->price * $count), 1);
//		$order->real_price = $requestData['real_price'];
//		$order->payment = $requestData['payment'];
//		if ($order->payment == 6) {
//			$order->member_id = $requestData['member_id'];
//			$order->member_card = $requestData['member_card'];
//		}
//		$order->status = config('constant.orderStatus')['done']; // 已完成
//		$order->is_pay = config('constant.yes');
//		$order->save();
//		// 理发师提成
//		return true;
//	}


//	/**
//	 * WX端订单查询
//	 * searchOrder
//	 */
//	public function searchOrder($requestData)
//	{
//		return $this->getByCriteria(new searchOrderWxCriteria($requestData));
//	}

	/**
	 * 理发师查询订单
	 * @param $storeId
	 * @param $status
	 * @param null $barberId
	 * @param null $pageSize
	 * @param null $orderNo
	 * @param null $mobile
	 * @param null $memberId
	 * @param bool $isOffline
	 * @param null $date
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function findOrderList($storeId, $status, $barberId = null, $pageSize = null, $keyword = null, $mobile = null, $memberId = null, $isOffline = false, $date = null)
	{
		return $this->pushCriteria(new findOrderAppBarberCriteria($storeId, $status, $barberId, $keyword, $mobile, $memberId, $isOffline, $date))->paginate($pageSize, ['*'], 'paginate');
	}

	/**
	 * 数据统计
	 * @param $storeId
	 * @param $status
	 * @param null $barberId
	 * @param bool $isOffline
	 * @param null $date
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function findOrderStatistics($storeId, $status, $barberId = null, $isOffline = false, $date = null)
	{
		$result = $this->getByCriteria(new findOrderStatisticsCriteria($storeId, $status, $barberId, $isOffline, $date));
		return [
			'ids'    => $result->pluck('id'),
			'amount' => $result->sum('real_price'),
			'count'  => $result->count()
		];
	}

	/**
	 * 检测订单是否存在
	 * @param $orderId
	 * @return mixed
	 * @throws NotFoundException
	 */
	public function isExisted($orderId)
	{
		$order = $this->find($orderId);
		if (empty($order)) {
			throw new NotFoundException(['msg' => '订单不存在']);
		}
		return $order;
	}

	/**
	 * 更新订单 完成和付款状态
	 * @param $orderId
	 * @param int $status
	 * @param int $isPay
	 * @return mixed
	 */
	public function updateById($orderId, $status = 1, $isPay = 0, $remark = null, $is_evaluate = 0)
	{
		$remark = empty($remark) ? '' : $remark;
		return $this->update(['status' => $status, 'is_pay' => $isPay, 'remark' => $remark, 'cancel_time' => time(), 'is_evaluate' => $is_evaluate], $orderId);

	}


	/**
	 * 今日服务 营业额  今日利润（待完成）
	 * @param $requestData
	 * @return array
	 */
	public function orderToday($requestData)
	{
		$requestData['date'] = date('Y-m-d', time());

		// 计算该店铺下所有的剪发师员工
		$usersId = (new StoreRepository())->getBarbersIds($requestData['store_id']);

		$orders = $this->getByCriteria(new orderTodayCriteria($requestData));
		// 订单数数
		$list['count'] = $orders->count();
		// 服务总额
		$serviceAmount = $orders->sum('real_price');
		//商品销售
		$salesAmount = 0;
		//今日营业额
		$list['turnover'] = $serviceAmount + $salesAmount;
		//固定支出
		$expenditure = (new StoreRepository())->find($requestData['store_id'])->expenditure;
		$days = date('t', time());
		$expenditureDay = round((floatval($expenditure) / floatval($days)), 2);
		$today = date('Y-m-d', time());

		$userSalary = (new RoyaltyRepository())->userSalary($requestData['store_id'], [1], $today);
		// 纯利润
		$list['profit'] = round(($list['turnover'] - $userSalary - $expenditureDay), 2);
		// 今日固定支出
		$list['expenditureDay'] = $expenditureDay;
		// 点击量 访问量
		$res = (new VisitHistoryRepository())->storeVisitorToday($requestData['store_id']);
		$list['visitor_nums'] = $res['visitor_nums'];
		$list['click_nums'] = $res['click_nums'];
		// 转化率
		$list['conversion_rate'] = empty($list['visitor_nums']) ? 0 : round($list['count'] / $list['visitor_nums'], 2);
		// 好评率
		$list['comment_good_rate'] = (new OrderCommentRepository())->getCommentGoodRate($requestData['store_id']);
		// 动态数
		$list['dynamic_nums'] = (new DynamicRepository())->count($usersId);

		return $list;
	}


	/**
	 * 理发师今日经营数据
	 * @param $requestData
	 * @return float|int|mixed
	 */
	public function orderBarberToday($requestData)
	{
		$date = isset($requestData['date']) ? $requestData['date'] : '';
		// 今日工资
		$todayInfo = $this->getSingleSalary($requestData['store_id'], $requestData['user_id'], $date);
		// 服务单数
		$todayInfo['service_num'] = isset($todayInfo['royalty_list'][config('constant.royaltyType.service')]) ? $todayInfo['royalty_list'][config('constant.royaltyType.service')]['nums'] : 0;

		// 今日积分
		$todayInfo['coin'] = (new UserCoinRepository())->getUserCoinDay($requestData);

		// 好评率
		$todayInfo['comment_good_rate'] = (new OrderCommentRepository())->getCommentGoodRate($requestData['store_id'], $requestData['user_id']);

		// 动态数
		$todayInfo['dynamic_nums'] = (new DynamicRepository())->count([$requestData['user_id']]);

		return $todayInfo;
	}

	/**
	 * 查询某天的营业额
	 * @param $storeId
	 * @param $date
	 * @return float
	 */
	public function turnOver($storeId, $date)
	{
		$params['store_id'] = $storeId;
		$params['date'] = $date;
		$orders = $this->getByCriteria(new orderTodayCriteria($params));
		// 订单数数
		$list['count'] = $orders->count();
		// 服务总额
		$serviceAmount = $orders->sum('real_price');
		//商品销售
		$salesAmount = 0;
		$turnOver = round($serviceAmount + $salesAmount, 2);
		return $turnOver;
	}

	/**
	 * 近7天营业额
	 * @param $storeId
	 * @return array
	 */
	public function weekTurnOver($requestData)
	{
		$storeId = $requestData['store_id'];
		$now = date('Y-m-d H:i:s', time());
		$timeStamp = time();
		$beforeWeek = strtotime("-1weeks", strtotime($now));
		$list = [];
		while ($beforeWeek < $timeStamp) {
			$date = date('Y-m-d', $timeStamp);
			$timeStamp -= 86400;
			$turnOver = $this->turnOver($storeId, $date);
			$list[] = [
				'date'     => $date,
				'turnOver' => $turnOver
			];
		}
		return $list;
	}

	/**
	 * 查询某个用户某天的工资情况
	 * @param $storeId
	 * @param $userId
	 * @param string $date
	 * @return float|int|mixed
	 */
	public function getSingleSalary($storeId, $userId, $date = null)
	{
		// 时间默认时间今天
		$date = empty($date) ? date('Y-m-d', time()) : $date;
		// 员工的今日提成
		$todayRoyalty = (new RoyaltyRepository())->getUserStoreTodayRoyalty($userId, $storeId, [], $date);
		// 计算员工的基本工资
		$baseSalary = (new UserStoreRepository())->getUserDailySalary($storeId, $userId, config('constant.role.barber'), strtotime($date));
		//总工资
		$Salary = [
			'total'        => round($baseSalary + $todayRoyalty['amount'], 2),
			'base'         => round($baseSalary, 2),
			'royalty'      => $todayRoyalty['amount'],
			'royalty_list' => $todayRoyalty['list'],
		];

		return $Salary;
	}


	/**
	 * 今日店铺的订单总价或者订单利润
	 * @param $storeId
	 * @param int $userId
	 * @param bool $isProfit
	 * @param null $dateList
	 * @return mixed
	 */
	public function getOrderAmount($storeId, $userId = 0, $isProfit = false, $dateList = null)
	{
		$map = empty($userId) ? ['store_id' => $storeId, 'status' => 2] : ['store_id' => $storeId, 'barber_id' => $userId, 'status' => 2];
		$field = $isProfit ? 'profit' : 'real_price';
		$model = $this->model->where($map);
		isset($dateList) ?
			$model->whereRaw('FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' . $dateList['start_date'] . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >= "' . $dateList['end_date'] . '"') :
			$model->whereRaw('FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') = "' . date('Y-m-d', time()) . '"');
		return $model->sum($field);
	}

	/**
	 * 获取店铺的员工工资列表
	 * @param $requestData
	 * @return mixed
	 */
	public function getStoreSalaryList($requestData)
	{
		$usersId = (new StoreRepository())->getBarbersIds($requestData['store_id']);
		$list['amount_salary'] = 0;
		$list['list'] = [];
		if (!empty($usersId)) {
			foreach ($usersId as $v) {
				$salary = $this->getSingleSalary($requestData['store_id'], $v);
				$list['list'][] = [
					'user_id'      => $v,
					'total'        => $salary['total'],
					'base'         => $salary['base'],
					'royalty'      => $salary['royalty'],
					'royalty_list' => $salary['royalty_list']
				];
				$list['amount_salary'] += $salary['total'];
			}
		}

		return $list;
	}


	/**
	 * 获取店铺的员工工资列表 -> 定时任务调用
	 * @param $requestData
	 * @return mixed
	 */
	public function storeSalaryList($storeId, $date = null)
	{
//        $usersId = (new StoreRepository())->getBarbersIds($storeId);
		$usersId = (new UserStoreRepository())->getUserListByStoreId($storeId);
		$usersId = empty($usersId) ? [] : array_column($usersId, 'uid');
		$list = [];
		if (!empty($usersId)) {
			foreach ($usersId as $v) {
				$salary = $this->getSingleSalary($storeId, $v, $date);
				$royaltyList = empty($salary['royalty_list']) ? [] : array_values($salary['royalty_list']);
				$list[] = [
					'user_id'     => $v,
					'store_id'    => $storeId,
					'amount'      => $salary['base'],
					'royalty'     => $salary['royalty'],
					'order_sum'   => empty($royaltyList[1]) ? 0 : $royaltyList[1]['nums'],
					'salary_date' => empty($date) ? strtotime('-1 day') : strtotime($date),
				];
			}
		}
		return $list;
	}


	public function salesRank($requestData)
	{
		// 理发师销售排名
		$date = isset($requestData['date']) ? $requestData['date'] : '';
		$list['barber_list'] = $this->orderRankList($requestData['store_id'], 'barber_id', $date);
		$list['service_list'] = $this->orderServiceRankList($requestData['store_id'], $date);
		return $list;
		// 服务销售排名
	}


	/**
	 * 理发师订单服务排行
	 * @param $storeId
	 * @param string $type
	 * @param string $date
	 * @return mixed
	 */
	public function orderRankList($storeId, $type = 'barber_id', $date = '')
	{
		$date = empty($date) ? date('Y-m-d', time()) : $date;
		$usersId = (new StoreRepository())->getBarbersIds($storeId);
		$list = $this->model->selectRaw('store_id,' . $type . ',count(id) as num,sum(real_price) as total_price')->whereIn('barber_id', $usersId)->whereDate('created_at', $date)->groupBy($type)->get();
		return $list;
	}


	/**
	 * 服务排行 某店某天
	 * @param $storeId
	 * @param string $date
	 * @return array
	 */
	public function orderServiceRankList($storeId, $date = '')
	{
		$date = empty($date) ? date('Y-m-d', time()) : $date;
		$status = [config('constant.orderStatus.done'), config('constant.orderStatus.comment')];
		$list = $this->model->where('store_id', $storeId)->whereIn('status', $status)->whereDate('created_at', $date)->select('*')->with([
			'item' => function ($query) use ($date) {
				$query->selectRaw('id,service_id,service_name,order_id,sum(count) as nums')->whereDate('created_at', $date)->groupBy('order_id');

			}
		])->get()->toArray();

		$newList = [];
		if (!empty($list)) {
			foreach ($list as $k => $v) {
				if (!empty($v['item'])) {
					if (!isset($newList[$v['item'][0]['service_id']])) {
						$newList[$v['item'][0]['service_id']] = [
							'service_id'   => $v['item'][0]['service_id'],
							'service_name' => $v['item'][0]['service_name'],
							'nums'         => $v['item'][0]['nums'],
						];
					} else {
						$newList[$v['item'][0]['service_id']]['nums'] += $v['item'][0]['nums'];
					}
				}
			}
		}
		return $newList;
	}


	/**
	 * 预约指定散客用户
	 * @param $requestData
	 * @return array
	 */
	public function weekCustoms($requestData)
	{
		$startTime = isset($requestData['date']) ? $requestData['date'] : date('Y-m-d', time());
		$endTime = date('Y-m-d', strtotime("-1weeks", strtotime($startTime)));
		$map = isset($requestData['user_id']) ? ['barber_id' => $requestData['user_id'], 'store_id' => $requestData['store_id']] : ['store_id' => $requestData['store_id']];

		$res = $this->model->where($map)->selectRaw('sum(case  when source!=3 then 1 else 0 end) as appoint_num,sum(case  when source=3 and is_appoint=0 then 1 else 0 end) as scattered_num, sum(case  when source=3 and is_appoint=1 then 1 else 0 end) as designated_num')->whereDate("created_at", "<=", $startTime)->whereDate("created_at", ">=", $endTime)->selectRaw('DATE_FORMAT(created_at, "%Y-%m-%d") as date')->groupBy('date')->orderBy('date', 'desc')->get()->toArray();
		$res = empty($res) ? [] : array_column($res, null, 'date');
		$weekStart = strtotime($startTime);
		$weekEnd = strtotime($endTime);
		while ($weekEnd < $weekStart) {
			$date = date('Y-m-d', $weekStart);

			$list[] = isset($res[$date]) ? $res[$date] : [
				'date'           => $date,
				'appoint_num'    => 0,
				'scattered_num'  => 0,
				'designated_num' => 0
			];
			$weekStart -= 86400;
		}
		return $list;
	}

	/**
	 * 订单排队个数
	 * @param $userId
	 * @param $storeId
	 * @return mixed
	 */
	public function getOrderCount($storeId, $userId = 0, $status = 2)
	{
		$where = empty($userId) ? [
			'store_id' => $storeId,
			'status'   => $status
		] : [
			'barber_id' => $userId,
			'store_id'  => $storeId,
			'status'    => $status
		];
		return $this->model->where($where)
			->whereRaw('FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') = "' . date('Y-m-d', time()) . '"')->count();
	}

	/**
	 * 预约订单数统计
	 * @param $storeId
	 * @param $userId
	 * @return mixed
	 */
	public function getAppointmentCount($storeId, $userId)
	{
		$where = empty($userId) ? ['store_id' => $storeId, 'status' => 1] : ['store_id' => $storeId, 'barber_id' => $userId, 'status' => 1];
		return $this->model->where($where)->whereHas('appointment', function ($v) {
			$v->whereRaw('FROM_UNIXTIME(appointment_time,\'%Y-%m-%d\') = "' . date('Y-m-d', time()) . '"');
		})->count();
	}

	/**
	 * 订单查询
	 * @param $memberId
	 * @param $status
	 * @param $orderNo
	 * @param $pageSize
	 * @return array
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function searchOrderList($memberId, $status, $pageSize, $orderNo = Null)
	{
		$pageSize = empty($pageSize) ? 10 : $pageSize;
		return $this->pushCriteria(new searchOrderWxCriteria($memberId, $status, $orderNo))->paginate($pageSize, ['*'], 'paginate');

	}

	// 计算店铺所有店铺的营业额
	public function getStoreAmount($date)
	{
		$amountList = $this->model->selectRaw('store_id,sum(real_price) as amount,sum(id) as count')->groupBy('store_id')->whereDate('created_at', $date)->get()->toArray();

		return empty($amountList) ? [] : array_column($amountList, null, 'store_id');
	}

	//获取理发师昨天订单数
	public function getBarberDateOrderNum($user_id, $store_id, $date)
	{
		return $this->model->where('barber_id', $user_id)
			->where('store_id', $store_id)
			->whereRaw('FROM_UNIXTIME(finish_time,"%Y-%m-%d")="' . $date . '"')
			->where('status', 2)
			->get()
			->count();
	}

	//获取理发师在某店昨天订单营业额
	public function getBarberDateOrderAmount($user_id, $store_id, $date)
	{

		return $this->model->where('barber_id', $user_id)
			->where('store_id', $store_id)
			->whereRaw('TO_DAYS( "' . $date . '" ) - FROM_UNIXTIME(finish_time,"%Y-%m-%d") >= 0')
			->whereRaw('TO_DAYS( "' . $date . '" ) - FROM_UNIXTIME(finish_time,"%Y-%m-%d") < 1')
			->where('status', 2)
			->get()
			->sum('price');
	}

	//获取理发师在某店某天指定用户占比
	public function getBarberDateAppointOrderRate($user_id, $store_id, $date)
	{

		$order_num = $this->getBarberDateOrderNum($user_id, $store_id, $date);

		//指定单数
		$apppint_order_num = $this->model->where('barber_id', $user_id)
			->where('store_id', $store_id)
			->where('is_appoint', 1)
			->whereRaw('FROM_UNIXTIME(finish_time,"%Y-%m-%d")="' . $date . '"')
			->get()
			->count();
		if ($order_num == 0) {
			$appoint_order_rate = 0;
		} else {
			$appoint_order_rate = ($apppint_order_num / $order_num);
		}

		return $appoint_order_rate;
	}


	/**
	 * 订单统计
	 * @param $storeId
	 * @param $date
	 * @param $compareDate
	 * @param bool $isOnline
	 * @return mixed
	 */
	public function getAmountRate($storeId, $date, $compareDate, $isOnline = false)
	{
		$model = $this->model
			->selectRaw('date(created_at) as dates, count(id) as counts')
			->whereRaw('(store_id=' . $storeId . ' and status=2 and date(created_at)="' . $date . '")')
			->orWhereRaw('(store_id=' . $storeId . ' and status=2 and date(created_at)="' . $compareDate . '") group by date(created_at)');
		if ($isOnline) $model->where('source', 1);
		return $model->get()->toArray();
	}

	/**
	 * 指定订单统计
	 * @param $storeId
	 * @param $date
	 * @param $compareDate
	 * @return mixed
	 * @author Happy dong
	 * @modifiedTime 2019-08-18 20:01
	 */
	public function getPointAmountRate($storeId, $date, $compareDate)
	{
		return $this->model
			->selectRaw('date(created_at) as dates, count(id) as counts')
			->whereRaw('(store_id=' . $storeId . ' and status=2 and is_appoint=1 and date(created_at)="' . $date . '")')
			->orWhereRaw('(store_id=' . $storeId . ' and status=2 and is_appoint=1 and date(created_at)="' . $compareDate . '") group by date(created_at)')
			->get()->toArray();
	}


	/**
	 * 获取订单列表
	 * @param $storeId
	 * @param $startDate
	 * @param $endDate
	 * @param null $pageSize
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 * @author Happy dong
	 * @modifiedTime 2019-08-19 15:10
	 */
	public function getOrderListByDays($storeId, $startDate, $endDate, $islist = false, $pageSize = null, $user_id = null)
	{
		$pageSize = empty($pageSize) ? 10 : $pageSize;
		$result = $this->pushCriteria(new getCenterOrderListCriteria($storeId, $startDate, $endDate, $islist, $user_id));
		if ($islist) {
			$list = $result->get();
		} else {
			$list = $result->paginate($pageSize, ['*'], 'paginate');
		}
		return $list;
	}

	/**
	 * 订单图形数据
	 * @param $storeId
	 * @param $startDate
	 * @param $endDate
	 * @param bool $isOnline
	 * @param null $user_id
	 * @return mixed
	 */
	public function getOrderGraphData($storeId, $startDate, $endDate, $isOnline = false, $user_id = null)
	{
		$opt = $isOnline ? '=' : '!=';
		$list = $this->model->where('source', $opt, '1');
		$isBarber = isset($user_id);
		if ($startDate == $endDate) {
			$newList = $list->selectRaw('SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 0 and FROM_UNIXTIME(finish_time,\'%H\') <= 3) THEN 1 ELSE 0 end) AS hour3,
 SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 3 and FROM_UNIXTIME(finish_time,\'%H\')  <= 6) THEN 1 ELSE 0 end) AS hour6,
 SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 6  and FROM_UNIXTIME(finish_time,\'%H\')  <= 9) THEN 1 ELSE 0 end) AS hour9,
 SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 9  and FROM_UNIXTIME(finish_time,\'%H\')  <= 12) THEN 1 ELSE 0 end) AS hour12,
 SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 12  and FROM_UNIXTIME(finish_time,\'%H\')  <= 15) THEN 1 ELSE 0 end) AS hour15,
 SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 15  and FROM_UNIXTIME(finish_time,\'%H\')  <= 18) THEN 1 ELSE 0 end) AS hour18,
 SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 18  and FROM_UNIXTIME(finish_time,\'%H\')  <= 21) THEN 1 ELSE 0 end) AS hour21,
 SUM(CASE WHEN (FROM_UNIXTIME(finish_time,\'%H\')  > 21  and FROM_UNIXTIME(finish_time,\'%H\')  <= 24) THEN 1 ELSE 0 end) AS hour24')
				->whereRaw('store_id = ' . $storeId . ' and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') ="' . $startDate . '"')
				->when($isBarber, function ($query) use ($user_id) {
					$query->where('barber_id', '=', $user_id);
				})
//	            ->toSql();
				->first();
		} else {
			$newList = $list->selectRaw('FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') as times, count(id) as order_count')
				->whereRaw('store_id in (' . $storeId . ') and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '"  group by times')
				->when($isBarber, function ($query) use ($user_id) {
					$query->where('barber_id', $user_id);
				})
				->get();
		}
		return $newList->toArray();

	}


	/**
	 * 订单饼图数据查询
	 * @param $storeId
	 * @param $startDate
	 * @param $endDate
	 * @return mixed
	 * @author Happy dong
	 * @modifiedTime 2019-08-19 16:05
	 */
	public function getPieChartData($storeId, $startDate, $endDate, $user_id = null)
	{
		$list = $this->model->selectRaw('hx_order.source,count(hx_order.id) as count');
//	        ->selectRaw('SUM(CASE WHEN (source = 1) THEN 1 ELSE 0 end) AS online_count,SUM(CASE WHEN (source <> 1) THEN 1 ELSE 0 end) AS offline_count');
		if ($startDate == $endDate) {
			$newList = $list
				->when($user_id, function ($query) use ($user_id) {
					$query->where('barber_id', $user_id);
				})
				->whereRaw('store_id in (' . $storeId . ') and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') ="' . $startDate . '"');
		} else {
			$newList = $list
				->when($user_id, function ($query) use ($user_id) {
					$query->where('barber_id', $user_id);
				})
				->whereRaw('store_id in (' . $storeId . ') and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '"');
		}
		$result = $newList->groupBy('source')->get()->toArray();
		return empty($result) ? $result : array_column($result, null, 'source');
	}


	/**
	 * 支付方式柱状图
	 * @param $storeId
	 * @param $startDate
	 * @param $endDate
	 * @return array
	 */
	public function getPaymentBarChartList($storeId, $startDate, $endDate)
	{
		$sql = 'SELECT p.id AS payment_id, p.NAME AS payment_name, count( o.id ) AS payment_count  FROM hx_payment_type AS p LEFT JOIN hx_order AS o ON p.id = o.payment  AND o.store_id = "' . $storeId . '"  AND FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '" AND o.`status` = 2  GROUP BY  p.id';
		return DB::select($sql);
	}


	/**
	 * 指定用户占比数据
	 * @param $storeId
	 * @param $startDate
	 * @param $endDate
	 * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model[]|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection
	 */
	public function getOrderPointData($storeId, $startDate, $endDate, $isLimit = 1)
	{
		$list = $this->model->with([
			'user' => function ($v) {
				$v->select(['id', 'portrait', 'nick'])->with('picture:id,image');
			}
		])
			->selectRaw('barber_id,count(id) as order_count,SUM(CASE WHEN (is_appoint = 1) THEN 1 ELSE 0 end) AS appoint_count')
			->whereRaw('store_id in (' . $storeId . ') and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '"')
			->groupBy('barber_id')
			->orderByDesc('appoint_count');
		if ($isLimit) $list->take(5);
		return $list->get();
	}


	/**
	 * 获取指定用户的订单列表
	 * @param $storeId
	 * @param $userId
	 * @param $startDate
	 * @param $endDate
	 * @param $pageSize
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getOrderPointList($storeId, $userId, $startDate, $endDate, $pageSize)
	{
		$pageSize = empty($pageSize) ? 10 : $pageSize;
		return $this->pushCriteria(new getOrderPointListCriteria($storeId, $userId, $startDate, $endDate))->paginate($pageSize, ['*'], 'paginate');
	}


	public function getAmountRankListByBarberId($storeId, $startDate, $endDate)
	{
		$sql = 'SELECT
	u.id as barber_id,
	u.nick as barber_name,
	u.username as username,
	sum( o.real_price ) AS counts
FROM
	hx_user AS u
	LEFT JOIN hx_user_store AS s ON u.id = s.uid
	LEFT JOIN hx_order AS o ON u.id = o.barber_id 
	AND FROM_UNIXTIME( o.finish_time, \'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(o.finish_time,\'%Y-%m-%d\') >="' . $endDate . '"  WHERE s.sid = "' . $storeId . '"   GROUP BY u.id order by counts desc';
		return DB::select($sql);
//        return $this->model
//            ->selectRaw('sum(real_price) as counts,barber_id')
//            ->with(['user'=>function($v){
//               $v->select(['id','nick','portrait'])->with('picture:id,image');
//            }])
//            ->whereRaw('store_id ="' . $storeId . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' .$startDate. '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '"  group by barber_id order by counts desc')
//
//            ->get();
	}


	public function getAmountRankListByBarberIdObject($storeId, $startDate, $endDate)
	{
		return $this->model
			->selectRaw('sum(real_price) as counts,barber_id')
			->with([
				'user' => function ($v) {
					$v->select(['id', 'nick', 'portrait'])->with('picture:id,image');
				}
			])
			->whereRaw('store_id ="' . $storeId . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '"  group by barber_id order by counts desc')
			->get();
	}

	public function getAmountRankListByBarberIdProfit($storeId, $startDate, $endDate)
	{
		return $this->model
			->selectRaw('sum(profit) as counts,barber_id')
			->with([
				'user' => function ($v) {
					$v->select(['id', 'nick', 'portrait'])->with('picture:id,image');
				}
			])
			->whereRaw('store_id ="' . $storeId . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '"  group by barber_id order by counts desc')
			->get();
	}


	public function getOrderRankListByBarberId($storeId, $startDate, $endDate)
	{

		$sql = 'SELECT
	u.id as barber_id,
	u.nick as barber_name,
	u.username as username,
	count( o.id ) AS counts
FROM
	hx_user AS u
	LEFT JOIN hx_user_store AS s ON u.id = s.uid
	LEFT JOIN hx_order AS o ON u.id = o.barber_id 
	AND FROM_UNIXTIME( o.finish_time, \'%Y-%m-%d\') <= "' . $startDate . '" and FROM_UNIXTIME(o.finish_time,\'%Y-%m-%d\') >="' . $endDate . '"  WHERE s.sid = "' . $storeId . '"   GROUP BY u.id order by counts desc';
		return DB::select($sql);


//        return $this->model
//            ->selectRaw('count(id) as counts, barber_id')
//            ->with('user:id,nick')
//
//
//            ->whereRaw('store_id ="' . $storeId . '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') <= "' .$startDate. '" and FROM_UNIXTIME(finish_time,\'%Y-%m-%d\') >="' . $endDate . '"  group by barber_id order by counts desc')
//
//            ->get();
	}

	/**
	 * 获取正在进行中的订单数
	 * @param $store_id
	 * @return mixed
	 */
	public function getUnderwayOrderNum($store_id)
	{
		return $this->model->where('store_id', $store_id)->where('status', 1)->get()->count();
	}


	/**
	 * 理发师贡献服务列表
	 * @param $storeId
	 * @param $barberId
	 * @param $startDate
	 * @param $endDate
	 * @param $pageSize
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getOrderServiceList($storeId, $barberId, $startDate, $endDate, $pageSize, $isProfit = 0)
	{
		$pageSize = empty($pageSize) ? 10 : $pageSize;
		return $this->pushCriteria(new getContributionOrderServiceListCriteria($storeId, $barberId, $startDate, $endDate, $isProfit))->paginate($pageSize, ['*'], 'paginate');

	}


	/**
	 * 理发师服务排名
	 * @param $storeId
	 * @param $barberId
	 * @param $startDate
	 * @param $endDate
	 * @param $pageSize
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
//	public function getOrderServiceDataList($storeId,$serviceId,$startDate,$endDate,$pageSize){
//
//		$sql = 'SELECT o.barber_id as barber_id, u.nick as barber_name, p.image as portrait, o.real_price AS total_price, FROM_UNIXTIME( o.finish_time, \'%Y-%m-%d %H:%i:%s\' ) as finish_time, sum( t.count ) AS counts FROM
//	hx_order AS o
//	LEFT JOIN hx_order_item AS t ON o.id = t.order_id AND t.service_id = "'.$serviceId.'"
//	LEFT JOIN hx_user as u  ON u.id=o.barber_id
//	LEFT JOIN hx_picture as p ON p.id=u.portrait
//	WHERE  FROM_UNIXTIME( o.finish_time, \'%Y-%m-%d\' ) <= "'.$startDate.'" AND FROM_UNIXTIME( o.finish_time, \'%Y-%m-%d\' ) >= "'.$endDate.'" AND o.store_id="'.$storeId.'"
//	GROUP BY o.id';
//		return DB::select($sql);
//
//	}


	public function getOrderNumBySource($store_id, $type)
	{
		return $this
			->where('source', $type)
			->where('store_id', $store_id)
			->count();
	}

	/**
	 * 过期订单设置
	 * @return array
	 */
	public function setExpiredOrder()
	{
		return DB::select('update hx_order as o left Join hx_appointment as a on o.`appointment_id` = a.`id`   set  o.`status`=4 where  o.`status` = 1 and FROM_UNIXTIME( a.`appointment_time`, \'%Y-%m-%d\' ) < "' . date('Y-m-d', time()) . '"');
	}


	/**
	 * 用户正在进行中的订单数量
	 * @param $memberId
	 * @return mixed
	 */
	public function getMemberOrderUnfinishedNum($memberId)
	{
		return $this->model->where(['member_id' => $memberId, 'status' => 1])->count();
	}


	/**
	 * 计算等级的订单数
	 * @param $storeId
	 * @return mixed
	 */
	public function getFinishedOrderNums($storeId)
	{
		$nums = config('constant.storeLevelIncludingOfflineOrders') ? $this->model : $this->model->where('source', '=', config('constant.appointment.online'));
		return $nums->where(['store_id' => $storeId, 'status' => config('constant.orderStatus.done')])->count();
	}

	/**
	 * 获取今日到某天前的订单营业额
	 * @param $user_id
	 * @param $store_id
	 * @param $end_day
	 */
	public function getAmountDate($user_id, $store_id, $end_day)
	{
		$end_day = strtotime($end_day);
		return $this->model->where('barber_id', $user_id)
			->where('finish_time', '>=', $end_day)
			->where('store_id', $store_id)
			->get()
			->sum('real_price');
	}

	/**
	 * 获取今日到某天前的指定用户占比
	 * @param $user_id
	 * @param $store_id
	 * @param $end_day
	 */
	public function getPointMemberRateDate($user_id, $store_id, $end_day)
	{
		$end_day = strtotime($end_day);
		$all = $this->model->where('barber_id', $user_id)
			->where('finish_time', '>=', $end_day)
			->where('store_id', $store_id)
			->get()
			->count();
		$point = $this->model->where('barber_id', $user_id)
			->where('finish_time', '>=', $end_day)
			->where('store_id', $store_id)
			->where('is_appoint', 1)
			->get()
			->count();
		if ($all == 0) {
			return 0;
		} else {
			return round($point / $all, 2);
		}

	}

	public function getServiceRateDate($store_id, $user_id, $end_day)
	{
		$end_day = strtotime($end_day);

		return $this
			->model
			->selectRaw('hx_order.id,count(*) as count,hx_store_service.type,sum(hx_order.real_price) as amount')
			->where('order.barber_id', $user_id)
			->where('order.finish_time', '>=', $end_day)
			->where('order.store_id', $store_id)
			->leftJoin('order_item', 'order_id', 'order.id')
			->leftJoin('store_service', 'order_item.service_id', 'store_service.id')
			->groupBy('store_service.type')
			->get();
	}

	public function getServiceTypeRoyalty($store_id, $user_id, $end_day)
	{
		$end_day = strtotime($end_day);

		return $this
			->model
			->selectRaw('hx_order.id,hx_store_service.type')
			->with([
				'royalty' => function ($query) use ($user_id) {
					$query->where('user_id', $user_id)->where('type', 1);
				}
			])
			->where('order.barber_id', $user_id)
			->where('order.finish_time', '>=', $end_day)
			->where('order.store_id', $store_id)
			->leftJoin('order_item', 'order_id', 'order.id')
			->leftJoin('store_service', 'order_item.service_id', 'store_service.id')
			->get();
	}

	/**
	 * 根据服务类型获取订单
	 * @param $store_id
	 * @param $user_id
	 * @param $end_day
	 * @param $type
	 * @return mixed
	 */
	public function getOrderByServiceType($store_id, $user_id, $end_day, $type)
	{
		$end_day = strtotime($end_day);

		$royalty_query = DB::table('royalty')
			->selectRaw('sum(amount) as amount,item_id,created_at')
			->where('user_id', $user_id)
			->where('store_id', $store_id)
			->where('type', 1)
			->groupBy('item_id');

		$select = [
			'hx_member.face as image',
			'hx_member.name as title',
			'hx_store_service.name as content',
			'hx_royalty.created_at',
			'hx_royalty.amount as profit',
			'hx_order.real_price as amount',
		];

		$select = implode($select, ',');

		return $this
			->model
			->selectRaw($select)
			->where('barber_id', $user_id)
			->where('finish_time', '>=', $end_day)
			->where('order.store_id', $store_id)
			->whereIn('store_service.type', $type)
			->leftJoin(\DB::raw("({$royalty_query->toSql()}) as hx_royalty"), function ($join) use ($royalty_query) {
				$join->mergeBindings($royalty_query)->on('royalty.item_id', '=', 'order.id');
			})
			->leftJoin('order_item', 'order_id', 'order.id')
			->leftJoin('member', 'order.member_id', 'member.id')
			->leftJoin('store_service', 'order_item.service_id', 'store_service.id');
	}


	public function getOrderList($storeId, $barberId, $isAppointment = false, $pageSize = 10)
	{
		$where = [['store_id', '=', $storeId], ['barber_id', '=', $barberId]];
		if ($isAppointment) array_push($where, ['appointment_id', '>', 0]);
		return $this->model->with([
			'user' => function ($v) {
				$v->select(['id', 'nick', 'portrait'])->with('picture:id,image');
			}
		])->where($where)->orderBy('created_at', 'desc')->paginate($pageSize)->toArray();
	}


	/**
	 * 查询订单列表
	 * @param $orderIds
	 * @param $keyword
	 * @param $is_barber
	 * @param $user_id
	 * @param $store_id
	 * @param $status
	 * @param $source
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getOrderListByIds($orderIds, $keyword, $is_barber, $user_id, $store_id, $status, $source)
	{
		return $this->pushCriteria(new GetOrderDetailInfoIncludeItemsByOrderIdCriteria($store_id, $is_barber, $user_id, $status, $source, $keyword, $orderIds))->get()->toArray();
	}


	/**
	 * 查询理发服务订单详情
	 * @param $orderId
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getOrderDetailInfo($orderId)
	{
		return $this->pushCriteria(new GetOrderDetailInfoIncludeItemsByOrderIdCriteria(null, null, null, null, null, null, $orderId))->first();
	}


	/**
	 * 客情分析 预约非预约
	 * @param $storeId
	 * @param $type
	 * @return array
	 */
	public function getAppointmentByStoreIdAndType($storeId,$category,$type,$one,$two)
	{
		if($category == 'appointment_id'){
			$whereOne = [$category=> ['>', 0]];
			$whereTwo = [$category=> ['=', 0]];
		}else{
			$whereOne = [$category=> ['=', 1]];
			$whereTwo = [$category=> ['=', 0]];
		}

		$appointmentDataModel = $this->model->where(['store_id'=>$storeId,'status' => 2])->where($whereOne);
		$intoStoreDataModel = $this->model->where(['store_id'=>$storeId,'status' => 2])->where($whereTwo);

		return [
			$one =>(int) ($type ? $appointmentDataModel->count() : $appointmentDataModel->sum('real_price')),
			$two  =>(int) ($type ? $intoStoreDataModel->count() : $intoStoreDataModel->sum('real_price')),
			'unit'        => $type ? '单' : '元',
		];
	}


}



